package com.tools.middle.redis.client;

import com.fasterxml.jackson.core.type.TypeReference;
import com.tools.common.object.C;
import com.tools.common.object.json.JsonKit;
import com.tools.common.object.Note;
import com.tools.common.object.ObjKit;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

import java.util.List;
import java.util.Set;

/**
 * Redis Set 集合类型的一些
 * 自定义封装的操作方法
 * */
@Note("Redis Set 集合类型的一些自定义封装的操作方法")
abstract class TypeSet extends TypeList {

    TypeSet() {}

    /* **********************************************************************************
     *
     *          同名 - 需要手动 close 的操作方法
     *
     * *********************************************************************************
     * */

    public long sadd(String key, Object value) {
        DataTypeKit.default_checkKey(key);
        Long result = this.jedis().sadd(key, ObjKit.toStringEmptyString(value));
        return DataTypeKit.default_returnResultLong(result);
    }

    public long sadd(String key, Object... values) {
        DataTypeKit.default_checkKey(key);
        Long result = this.jedis().sadd(key, DataTypeKit.default_asStringArray(values));
        return DataTypeKit.default_returnResultLong(result);
    }

    public long sadd(String key, Iterable values) {
        DataTypeKit.default_checkKey(key);
        Long result = this.jedis().sadd(key, DataTypeKit.default_asStringArray(values));
        return DataTypeKit.default_returnResultLong(result);
    }

    public boolean sismember(String key, Object value) {
        DataTypeKit.default_checkKey(key);
        Boolean result = this.jedis().sismember(key, ObjKit.toStringEmptyString(value));
        return result != null && result;
    }

    @Note("获取 Set 集合的容量")
    public long scard(String key) {
        DataTypeKit.default_checkKey(key);
        Long result = this.jedis().scard(key);
        return DataTypeKit.default_returnResultLong(result);
    }

    public Set<Object> smembers(String key) {
        DataTypeKit.default_checkKey(key);
        Set<String> results = this.jedis().smembers(key);
        return DataTypeKit.default_asObjectSet(results);
    }

    public <T> Set<T> smembers(String key, Class<T> valueType) {
        DataTypeKit.default_checkKey(key);
        Set<String> results = this.jedis().smembers(key);
        return DataTypeKit.default_asSpecifyTypeSet(results, valueType);
    }

    public <T> Set<T> smembers(String key, TypeReference<T> valueType) {
        DataTypeKit.default_checkKey(key);
        Set<String> results = this.jedis().smembers(key);
        return DataTypeKit.default_asSpecifyTypeSet(results, valueType);
    }

    public <T> Set<T> smembers(String key, C<T> valueType) {
        DataTypeKit.default_checkKey(key);
        Set<String> results = this.jedis().smembers(key);
        return DataTypeKit.default_asSpecifyTypeSet(results, valueType);
    }

    public long srem(String key, Object value) {
        DataTypeKit.default_checkKey(key);
        Long result = this.jedis().srem(key, ObjKit.toStringEmptyString(value));
        return DataTypeKit.default_returnResultLong(result);
    }

    public long srem(String key, Object... values) {
        DataTypeKit.default_checkKey(key);
        Long result = this.jedis().srem(key, DataTypeKit.default_asStringArray(values));
        return DataTypeKit.default_returnResultLong(result);
    }

    public long srem(String key, Iterable values) {
        DataTypeKit.default_checkKey(key);
        Long result = this.jedis().srem(key, DataTypeKit.default_asStringArray(values));
        return DataTypeKit.default_returnResultLong(result);
    }

    public Object spop(String key) {
        DataTypeKit.default_checkKey(key);
        String res = this.jedis().spop(key);
        return ObjKit.stringToRealValue(res, true);
    }

    public <T> T spop(String key, Class<T> valueType) {
        DataTypeKit.default_checkKey(key);
        String res = this.jedis().spop(key);
        return JsonKit.toEntity(res, valueType);
    }

    public <T> T spop(String key, TypeReference<T> valueType) {
        DataTypeKit.default_checkKey(key);
        String res = this.jedis().spop(key);
        return JsonKit.toEntity(res, valueType);
    }

    public <T> T spop(String key, C<T> valueType) {
        DataTypeKit.default_checkKey(key);
        String res = this.jedis().spop(key);
        return (T) ObjKit.stringToRealValue(res, valueType);
    }

    public Set<Object> spop(String key, long count) {
        DataTypeKit.default_checkKey(key);
        Set<String> res = this.jedis().spop(key, count);
        return DataTypeKit.default_asObjectSet(res);
    }

    public <T> Set<T> spop(String key, long count, Class<T> valueType) {
        DataTypeKit.default_checkKey(key);
        Set<String> res = this.jedis().spop(key, count);
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> spop(String key, long count, TypeReference<T> valueType) {
        DataTypeKit.default_checkKey(key);
        Set<String> res = this.jedis().spop(key, count);
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> spop(String key, long count, C<T> valueType) {
        DataTypeKit.default_checkKey(key);
        Set<String> res = this.jedis().spop(key, count);
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    @Note("将 srcKey 中的 value 移动到 tarKey 集合中去")
    public long smove(String srcKey, String tarKey, Object value) {
        DataTypeKit.default_checkKey(srcKey);
        DataTypeKit.default_checkKey(tarKey);
        Long result = this.jedis().smove(srcKey, tarKey, ObjKit.toStringEmptyString(value));
        return DataTypeKit.default_returnResultLong(result);
    }

    @Note("随机返回一个元素")
    public Object srandmember(String key) {
        DataTypeKit.default_checkKey(key);
        String res = this.jedis().srandmember(key);
        return ObjKit.stringToRealValue(res, true);
    }

    public <T> T srandmember(String key, Class<T> valueType) {
        DataTypeKit.default_checkKey(key);
        String res = this.jedis().srandmember(key);
        return JsonKit.toEntity(res, valueType);
    }

    public <T> T srandmember(String key, TypeReference<T> valueType) {
        DataTypeKit.default_checkKey(key);
        String res = this.jedis().srandmember(key);
        return JsonKit.toEntity(res, valueType);
    }

    public <T> T srandmember(String key, C<T> valueType) {
        DataTypeKit.default_checkKey(key);
        String res = this.jedis().srandmember(key);
        return (T) ObjKit.stringToRealValue(res, valueType);
    }


    public List<Object> srandmember(String key, int count) {
        DataTypeKit.default_checkKey(key);
        List<String> res = this.jedis().srandmember(key, count);
        return DataTypeKit.default_asObjectList(res);
    }

    public <T> List<T> srandmember(String key, int count, Class<T> valueType) {
        DataTypeKit.default_checkKey(key);
        List<String> res = this.jedis().srandmember(key, count);
        return DataTypeKit.default_asSpecifyTypeList(res, valueType);
    }

    public <T> List<T> srandmember(String key, int count, TypeReference<T> valueType) {
        DataTypeKit.default_checkKey(key);
        List<String> res = this.jedis().srandmember(key, count);
        return DataTypeKit.default_asSpecifyTypeList(res, valueType);
    }

    public <T> List<T> srandmember(String key, int count, C<T> valueType) {
        DataTypeKit.default_checkKey(key);
        List<String> res = this.jedis().srandmember(key, count);
        return DataTypeKit.default_asSpecifyTypeList(res, valueType);
    }

    @Note("取多个集合的交集部分返回")
    public Set<Object> sinter(String... keys) {
        DataTypeKit.default_checkKeys(keys);
        Set<String> res = this.jedis().sinter(keys);
        return DataTypeKit.default_asObjectSet(res);
    }

    public Set<Object> sinter(Iterable<String> keys) {
        Set<String> res = this.jedis().sinter(DataTypeKit.default_asStringKeyArray(keys));
        return DataTypeKit.default_asObjectSet(res);
    }

    public <T> Set<T> sinter(Class<T> valueType, String... keys) {
        DataTypeKit.default_checkKeys(keys);
        Set<String> res = this.jedis().sinter(keys);
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sinter(Class<T> valueType, Iterable<String> keys) {
        Set<String> res = this.jedis().sinter(DataTypeKit.default_asStringKeyArray(keys));
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sinter(TypeReference<T> valueType, String... keys) {
        DataTypeKit.default_checkKeys(keys);
        Set<String> res = this.jedis().sinter(keys);
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sinter(TypeReference<T> valueType, Iterable<String> keys) {
        Set<String> res = this.jedis().sinter(DataTypeKit.default_asStringKeyArray(keys));
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sinter(C<T> valueType, String... keys) {
        DataTypeKit.default_checkKeys(keys);
        Set<String> res = this.jedis().sinter(keys);
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sinter(C<T> valueType, Iterable<String> keys) {
        Set<String> res = this.jedis().sinter(DataTypeKit.default_asStringKeyArray(keys));
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    @Note("取多个集合的差集部分返回")
    public Set<Object> sdiff(String... keys) {
        DataTypeKit.default_checkKeys(keys);
        Set<String> res = this.jedis().sdiff(keys);
        return DataTypeKit.default_asObjectSet(res);
    }

    public Set<Object> sdiff(Iterable<String> keys) {
        Set<String> res = this.jedis().sdiff(DataTypeKit.default_asStringKeyArray(keys));
        return DataTypeKit.default_asObjectSet(res);
    }

    public <T> Set<T> sdiff(Class<T> valueType, String... keys) {
        DataTypeKit.default_checkKeys(keys);
        Set<String> res = this.jedis().sdiff(keys);
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sdiff(Class<T> valueType, Iterable<String> keys) {
        Set<String> res = this.jedis().sdiff(DataTypeKit.default_asStringKeyArray(keys));
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }
    
    public <T> Set<T> sdiff(TypeReference<T> valueType, String... keys) {
        DataTypeKit.default_checkKeys(keys);
        Set<String> res = this.jedis().sdiff(keys);
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sdiff(TypeReference<T> valueType, Iterable<String> keys) {
        Set<String> res = this.jedis().sdiff(DataTypeKit.default_asStringKeyArray(keys));
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sdiff(C<T> valueType, String... keys) {
        DataTypeKit.default_checkKeys(keys);
        Set<String> res = this.jedis().sdiff(keys);
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sdiff(C<T> valueType, Iterable<String> keys) {
        Set<String> res = this.jedis().sdiff(DataTypeKit.default_asStringKeyArray(keys));
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    @Note("取多个集合的并集返回")
    public Set<Object> sunion(String... keys) {
        DataTypeKit.default_checkKeys(keys);
        Set<String> res = this.jedis().sunion(keys);
        return DataTypeKit.default_asObjectSet(res);
    }

    public Set<Object> sunion(Iterable<String> keys) {
        Set<String> res = this.jedis().sunion(DataTypeKit.default_asStringKeyArray(keys));
        return DataTypeKit.default_asObjectSet(res);
    }

    public <T> Set<T> sunion(Class<T> valueType, String... keys) {
        DataTypeKit.default_checkKeys(keys);
        Set<String> res = this.jedis().sunion(keys);
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sunion(Class<T> valueType, Iterable<String> keys) {
        Set<String> res = this.jedis().sunion(DataTypeKit.default_asStringKeyArray(keys));
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sunion(TypeReference<T> valueType, String... keys) {
        DataTypeKit.default_checkKeys(keys);
        Set<String> res = this.jedis().sunion(keys);
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sunion(TypeReference<T> valueType, Iterable<String> keys) {
        Set<String> res = this.jedis().sunion(DataTypeKit.default_asStringKeyArray(keys));
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sunion(C<T> valueType, String... keys) {
        DataTypeKit.default_checkKeys(keys);
        Set<String> res = this.jedis().sunion(keys);
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    public <T> Set<T> sunion(C<T> valueType, Iterable<String> keys) {
        Set<String> res = this.jedis().sunion(DataTypeKit.default_asStringKeyArray(keys));
        return DataTypeKit.default_asSpecifyTypeSet(res, valueType);
    }

    @Note("游标 cursor 的初始值为【0】，当返回的游标值再度为【0】 时才代表整体遍历结束" +
            "返回值是批量的 key 和下一次开始游标。" +
            "返回的结果可能会有重复，需要自己去重")
    public ScanResult<String> sscan(String key, String cursor) {
        DataTypeKit.default_checkKey(key);
        if(cursor == null || cursor.isEmpty()) cursor = "0";
        return this.jedis().sscan(key, cursor);
    }

    @Note("ScanParams 是可以设置 count（返回 key 的个数）和 match（正则匹配）的")
    public ScanResult<String> sscan(String key, String cursor, ScanParams params) {
        DataTypeKit.default_checkKey(key);
        if(cursor == null || cursor.isEmpty()) cursor = "0";
        if(params == null) return sscan(key, cursor);
        return this.jedis().sscan(key, cursor, params);
    }

    @Note("取多个集合的差集，然后保存到 tarKey 中")
    public long sdiffstore(String tarKey, String... srcKeys) {
        DataTypeKit.default_checkKey(tarKey);
        DataTypeKit.default_checkKeys(srcKeys);
        Long result = this.jedis().sdiffstore(tarKey, srcKeys);
        return DataTypeKit.default_returnResultLong(result);
    }

    public long sdiffstore(String tarKey, Iterable<String> srcKeys) {
        DataTypeKit.default_checkKey(tarKey);
        Long result = this.jedis().sdiffstore(tarKey, DataTypeKit.default_asStringKeyArray(srcKeys));
        return DataTypeKit.default_returnResultLong(result);
    }
    

    @Note("取多个集合的交集，然后保存到 tarKey 中")
    public long sinterstore(String tarKey, String... srcKeys) {
        DataTypeKit.default_checkKey(tarKey);
        DataTypeKit.default_checkKeys(srcKeys);
        Long result = this.jedis().sinterstore(tarKey, srcKeys);
        return DataTypeKit.default_returnResultLong(result);
    }

    public long sinterstore(String tarKey, Iterable<String> srcKeys) {
        DataTypeKit.default_checkKey(tarKey);
        Long result = this.jedis().sinterstore(tarKey, DataTypeKit.default_asStringKeyArray(srcKeys));
        return DataTypeKit.default_returnResultLong(result);
    }


    @Note("取多个集合的并集保存到 tarKey 中")
    public long sunionstore(String tarKey, String... srcKeys) {
        DataTypeKit.default_checkKey(tarKey);
        DataTypeKit.default_checkKeys(srcKeys);
        Long result = this.jedis().sunionstore(tarKey, srcKeys);
        return DataTypeKit.default_returnResultLong(result);
    }

    public long sunionstore(String tarKey, Iterable<String> srcKeys) {
        DataTypeKit.default_checkKey(tarKey);
        Long result = this.jedis().sunionstore(tarKey, DataTypeKit.default_asStringKeyArray(srcKeys));
        return DataTypeKit.default_returnResultLong(result);
    }

    /* **********************************************************************************
     *
     *          带【$】 - 自动 close 的操作方法
     *
     * *********************************************************************************
     * */

    public long sadd$(String key, Object value) {
        try {
            return this.sadd(key, value);
        } finally {
            this.close();
        }
    }

    public long sadd$(String key, Object... values) {
        try {
            return this.sadd(key, values);
        } finally {
            this.close();
        }
    }

    public long sadd$(String key, Iterable values) {
        try {
            return this.sadd(key, values);
        } finally {
            this.close();
        }
    }


    public boolean sismember$(String key, Object value) {
        try {
            return this.sismember(key, value);
        } finally {
            this.close();
        }
    }

    public long scard$(String key) {
        try {
            return this.scard(key);
        } finally {
            this.close();
        }
    }

    public Set<Object> smembers$(String key) {
        try {
            return this.smembers(key);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> smembers$(String key, Class<T> valueType) {
        try {
            return this.smembers(key, valueType);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> smembers$(String key, TypeReference<T> valueType) {
        try {
            return this.smembers(key, valueType);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> smembers$(String key, C<T> valueType) {
        try {
            return this.smembers(key, valueType);
        } finally {
            this.close();
        }
    }


    public long srem$(String key, Object value) {
        try {
            return this.srem(key, value);
        } finally {
            this.close();
        }
    }

    public long srem$(String key, Object... values) {
        try {
            return this.srem(key, values);
        } finally {
            this.close();
        }
    }

    public long srem$(String key, Iterable values) {
        try {
            return this.srem(key, values);
        } finally {
            this.close();
        }
    }

    public Object spop$(String key) {
        try {
            return this.spop(key);
        } finally {
            this.close();
        }
    }

    public <T> T spop$(String key, Class<T> valueType) {
        try {
            return this.spop(key, valueType);
        } finally {
            this.close();
        }
    }

    public <T> T spop$(String key, TypeReference<T> valueType) {
        try {
            return this.spop(key, valueType);
        } finally {
            this.close();
        }
    }

    public <T> T spop$(String key, C<T> valueType) {
        try {
            return this.spop(key, valueType);
        } finally {
            this.close();
        }
    }

    public Set<Object> spop$(String key, long count) {
        try {
            return this.spop(key, count);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> spop$(String key, long count, Class<T> valueType) {
        try {
            return this.spop(key, count, valueType);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> spop$(String key, long count, TypeReference<T> valueType) {
        try {
            return this.spop(key, count, valueType);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> spop$(String key, long count, C<T> valueType) {
        try {
            return this.spop(key, count, valueType);
        } finally {
            this.close();
        }
    }

    @Note("将 srcKey 中的 value 移动到 tarKey 集合中去")
    public long smove$(String srcKey, String tarKey, Object value) {
        try {
            return this.smove(srcKey, tarKey, value);
        } finally {
            this.close();
        }
    }

    @Note("随机返回一个元素")
    public Object srandmember$(String key) {
        try {
            return this.srandmember(key);
        } finally {
            this.close();
        }
    }

    public <T> T srandmember$(String key, Class<T> valueType) {
        try {
            return this.srandmember(key, valueType);
        } finally {
            this.close();
        }
    }

    public <T> T srandmember$(String key, TypeReference<T> valueType) {
        try {
            return this.srandmember(key, valueType);
        } finally {
            this.close();
        }
    }

    public <T> T srandmember$(String key, C<T> valueType) {
        try {
            return this.srandmember(key, valueType);
        } finally {
            this.close();
        }
    }

    public List<Object> srandmember$(String key, int count) {
        try {
            return this.srandmember(key, count);
        } finally {
            this.close();
        }
    }

    public <T> List<T> srandmember$(String key, int count, Class<T> valueType) {
        try {
            return this.srandmember(key, count, valueType);
        } finally {
            this.close();
        }
    }

    public <T> List<T> srandmember$(String key, int count, TypeReference<T> valueType) {
        try {
            return this.srandmember(key, count, valueType);
        } finally {
            this.close();
        }
    }

    public <T> List<T> srandmember$(String key, int count, C<T> valueType) {
        try {
            return this.srandmember(key, count, valueType);
        } finally {
            this.close();
        }
    }

    @Note("取多个集合的交集部分返回")
    public Set<Object> sinter$(String... keys) {
        try {
            return this.sinter(keys);
        } finally {
            this.close();
        }
    }

    public Set<Object> sinter$(Iterable<String> keys) {
        try {
            return this.sinter(keys);
        } finally {
            this.close();
        }
    }


    public <T> Set<T> sinter$(Class<T> valueType, String... keys) {
        try {
            return this.sinter(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sinter$(Class<T> valueType, Iterable<String> keys) {
        try {
            return this.sinter(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sinter$(TypeReference<T> valueType, String... keys) {
        try {
            return this.sinter(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sinter$(TypeReference<T> valueType, Iterable<String> keys) {
        try {
            return this.sinter(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sinter$(C<T> valueType, String... keys) {
        try {
            return this.sinter(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sinter$(C<T> valueType, Iterable<String> keys) {
        try {
            return this.sinter(valueType, keys);
        } finally {
            this.close();
        }
    }


    @Note("取多个集合的差集部分返回")
    public Set<Object> sdiff$(String... keys) {
        try {
            return this.sdiff(keys);
        } finally {
            this.close();
        }
    }

    public Set<Object> sdiff$(Iterable<String> keys) {
        try {
            return this.sdiff(keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sdiff$(Class<T> valueType, String... keys) {
        try {
            return this.sdiff(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sdiff$(Class<T> valueType, Iterable<String> keys) {
        try {
            return this.sdiff(valueType, keys);
        } finally {
            this.close();
        }
    }


    public <T> Set<T> sdiff$(TypeReference<T> valueType, String... keys) {
        try {
            return this.sdiff(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sdiff$(TypeReference<T> valueType, Iterable<String> keys) {
        try {
            return this.sdiff(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sdiff$(C<T> valueType, String... keys) {
        try {
            return this.sdiff(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sdiff$(C<T> valueType, Iterable<String> keys) {
        try {
            return this.sdiff(valueType, keys);
        } finally {
            this.close();
        }
    }


    @Note("取多个集合的并集返回")
    public Set<Object> sunion$(String... keys) {
        try {
            return this.sunion(keys);
        } finally {
            this.close();
        }
    }

    public Set<Object> sunion$(Iterable<String> keys) {
        try {
            return this.sunion(keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sunion$(Class<T> valueType, String... keys) {
        try {
            return this.sunion(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sunion$(Class<T> valueType, Iterable<String> keys) {
        try {
            return this.sunion(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sunion$(TypeReference<T> valueType, String... keys) {
        try {
            return this.sunion(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sunion$(TypeReference<T> valueType, Iterable<String> keys) {
        try {
            return this.sunion(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sunion$(C<T> valueType, String... keys) {
        try {
            return this.sunion(valueType, keys);
        } finally {
            this.close();
        }
    }

    public <T> Set<T> sunion$(C<T> valueType, Iterable<String> keys) {
        try {
            return this.sunion(valueType, keys);
        } finally {
            this.close();
        }
    }

    public ScanResult<String> sscan$(String key, String cursor) {
        try {
            return this.sscan(key, cursor);
        } finally {
            this.close();
        }
    }

    @Note("ScanParams 是可以设置 count（返回 key 的个数）和 match（正则匹配）的")
    public ScanResult<String> sscan$(String key, String cursor, ScanParams params) {
        try {
            return this.sscan(key, cursor, params);
        } finally {
            this.close();
        }
    }


    @Note("取多个集合的差集，然后保存到 tarKey 中")
    public long sdiffstore$(String tarKey, String... srcKeys) {
        try {
            return this.sdiffstore(tarKey, srcKeys);
        } finally {
            this.close();
        }
    }

    public long sdiffstore$(String tarKey, Iterable<String> srcKeys) {
        try {
            return this.sdiffstore(tarKey, srcKeys);
        } finally {
            this.close();
        }
    }

    @Note("取多个集合的交集，然后保存到 tarKey 中")
    public long sinterstore$(String tarKey, String... srcKeys) {
        try {
            return this.sinterstore(tarKey, srcKeys);
        } finally {
            this.close();
        }
    }

    public long sinterstore$(String tarKey, Iterable<String> srcKeys) {
        try {
            return this.sinterstore(tarKey, srcKeys);
        } finally {
            this.close();
        }
    }


    @Note("取多个集合的并集保存到 tarKey 中")
    public long sunionstore$(String tarKey, String... srcKeys) {
        try {
            return this.sunionstore(tarKey, srcKeys);
        } finally {
            this.close();
        }
    }

    public long sunionstore$(String tarKey, Iterable<String> srcKeys) {
        try {
            return this.sunionstore(tarKey, srcKeys);
        } finally {
            this.close();
        }
    }
    
}
